<template>
  <ElDialog
    title="飞行轨迹"
    width="740px"
    class="select-map-dialog"
    v-model="dialogShow"
    :close-on-click-modal="false"
    :modal-append-to-body="false"
    :append-to-body="true"
    @close="handleClose"
  >
    <div class="amap-box">
      <div id="custom-amap"></div>
      <!-- 添加加载状态和错误提示 -->
      <div v-if="loading" class="map-loading">地图加载中...</div>
      <div v-if="error" class="map-error">{{ error }}</div>
    </div>
  </ElDialog>
</template>

<script type="text/javascript">
// 必须在AMap JS加载前设置安全配置
window._AMapSecurityConfig = {
  securityJsCode: mapSetting?.mapSecurity || "",
};
</script>

<script setup>
import { ref, onUnmounted, watch, computed, nextTick } from "vue";
import { ElMessage, ElInput, ElDialog, ElButton } from "element-plus";
import AMapLoader from "@amap/amap-jsapi-loader";
import { mapSetting } from "#/api/map";

const map = ref(null); // 地图对象
const loca = ref(null); // 实例
const defaultCenter = [119.904953, 30.251849];
const loading = ref(false);
const error = ref(null);
// 总数据
const allData = ref([
  {
    points: [],
    lineData: [],
    guideLineData: [],
    // startdata: {
    //   point: null,
    //   lineData: null,
    //   guideLineData: null,
    //   marker: null,
    // },
  },
]);
let defaultHeight = 200; // 默认高度
const offset = 0.00001; // 约1米偏移，确保线段可见
const satelliteLayer = ref(null);
const roadNetLayer = ref(null);

const props = defineProps({
  drawDefaultRoute: {
    type: Array,
    default: () => [], // 默认航线数据
  },
  isShow: {
    type: Boolean,
    default: false,
  },
});
console.log("props", props);

const emits = defineEmits(["update:isShow", "close"]);

// 对话框显示状态
const dialogShow = computed({
  get: () => props.isShow,
  set: (val) => emits("update:isShow", val),
});

// 清理地图资源
const cleanupMap = () => {
  try {
    // 清理标记
    if (allData.value && allData.value.length > 0) {
      // 清理起飞点标记
      // if (allData.value[0].startdata && allData.value[0].startdata.marker) {
      //   if (map.value) {
      //     map.value.remove(allData.value[0].startdata.marker);
      //   }
      //   allData.value[0].startdata.marker = null;
      // }

      // 清理航点标记
      if (allData.value[0].markers && allData.value[0].markers.length > 0) {
        allData.value[0].markers.forEach((marker) => {
          if (map.value) {
            map.value.remove(marker);
          }
        });
        allData.value[0].markers = [];
      }
    }

    // 销毁Loca容器
    if (loca.value) {
      loca.value.destroy();
      loca.value = null;
    }

    // 销毁地图实例
    if (map.value) {
      map.value.destroy();
      map.value = null;
    }

    // 清理全局变量
    if (window.lineLayer) {
      window.lineLayer = null;
    }
    if (window.guideLineLayer) {
      window.guideLineLayer = null;
    }

    // 重置数据
    allData.value = [
      {
        points: [],
        lineData: [],
        guideLineData: [],
        // startdata: {
        //   point: null,
        //   lineData: null,
        //   guideLineData: null,
        //   marker: null,
        // },
        markers: [],
      },
    ];
  } catch (e) {
    console.warn("地图清理失败:", e);
  }
};

// 处理关闭事件
const handleClose = () => {
  cleanupMap();
  emits("update:isShow", false);
};

// 监听对话框显示状态
watch(
  () => props.isShow,
  (newVal) => {
    if (newVal) {
      console.log("props-watch", props);
      nextTick().then(() => {
        if (!map.value) {
          initMap();
        } else {
          if (props.drawDefaultRoute && props.drawDefaultRoute.length > 0) {
            drawFlightPath(window.AMap);
          }
        }
      });
    } else {
      // 延迟清理避免同步问题，且只在确认关闭时清理
      setTimeout(() => {
        // 确保仍然处于关闭状态再清理
        if (!props.isShow) {
          cleanupMap();
        }
      }, 100);
    }
  },
  { immediate: false }
);

// 计算整数化倍数：
const integerOperation = (val1, val2) => {
  // 添加参数验证
  if (
    val1 === undefined ||
    val1 === null ||
    val2 === undefined ||
    val2 === null
  ) {
    console.error("integerOperation: 参数不能为undefined或null", {
      val1,
      val2,
    });
    return 1; // 返回默认值
  }

  const val1DecimalIndex = val1.toString().indexOf("."); // 获取数值1的小数位的长度
  const len1 =
    val1DecimalIndex === -1 ? 0 : val1.toString().length - val1DecimalIndex - 1;
  const val2DecimalIndex = val2.toString().indexOf("."); // 获取数值2的小数位的长度
  const len2 =
    val2DecimalIndex === -1 ? 0 : val2.toString().length - val2DecimalIndex - 1;
  const p = Math.max(len1, len2); // 获取大的小数位数
  // 避免最终求出结果的长度大于最大长度的时候导致精度丢失 开启下面
  // p += p - Math.min(len1, len2);
  return Math.pow(10, p); // Math.pow() 计算一个数的指定次幂的方法 10的p次方
};

// 解决浮点数运算的精度
const arithmetic = {
  add(val1, val2) {
    const p = integerOperation(val1, val2);
    return (val1 * p + val2 * p) / p;
  },
  subtract(val1, val2) {
    const p = integerOperation(val1, val2);
    return (val1 * p - val2 * p) / p;
  },
  multiply(val1, val2) {
    const p = integerOperation(val1, val2);
    return (val1 * p * (val2 * p)) / (p * p);
  },
  division(val1, val2) {
    const p = integerOperation(val1, val2);
    return (val1 * p) / (val2 * p) / (p * p);
  },
};

// 设置浮空线段
const flayLine = (locaInstance) => {
  if (window.Loca && locaInstance) {
    try {
      // 创建 LineLayer（浮空线段）
      const lineLayer = new window.Loca.LineLayer({
        zIndex: 100, // 确保图层在上层
      });

      // 创建辅助线图层
      const guideLineLayer = new window.Loca.LaserLayer({
        zIndex: 55, // 确保辅助线在底层但可见
        zooms: [2, 20], //
      });

      // 设置 LineLayer 数据源
      lineLayer.setSource(
        new window.Loca.GeoJSONSource({
          data: {
            type: "FeatureCollection",
            features: [],
          },
        })
      );

      // 设置辅助线图层数据源
      guideLineLayer.setSource(
        new window.Loca.GeoJSONSource({
          data: {
            type: "FeatureCollection",
            features: [],
          },
        })
      );

      // 设置辅助线样式 - 使用静态线条
      guideLineLayer.setStyle({
        altitude: true, // 启用高度
        lineWidth: 3, // 线条宽度
        color: "#f0ed7a", // 黄色辅助线
      });

      // 设置 LineLayer 样式 浮空线段样式
      lineLayer.setStyle({
        altitude: true, // 启用高度
        lineWidth: 5, // 线段宽度
        color: "#00d58f", // 颜色属性名改为 color
      });

      // 将图层添加到loca容器
      locaInstance.add(lineLayer);
      locaInstance.add(guideLineLayer);

      // 保存图层引用到全局变量
      window.lineLayer = lineLayer;
      window.guideLineLayer = guideLineLayer;

      // 启动激光线动画
      if (locaInstance && locaInstance.animate) {
        locaInstance.animate.start();
      }
    } catch (error) {
      console.error("flayLine 创建图层时出错:", error);
    }
  } else {
    console.error("flayLine 条件不满足:");
    console.error("window.Loca:", window.Loca);
    console.error("locaInstance:", locaInstance);
  }
};

// 初始化地图
const initMap = async () => {
  // 即使地图存在也要重新初始化，以确保正确显示
  if (!dialogShow.value) return;

  loading.value = true;
  error.value = null;

  try {
    // 如果地图已存在，先销毁
    if (map.value) {
      cleanupMap();
    }

    const AMap = await AMapLoader.load({
      key: mapSetting?.mapKey || "",
      version: "2.0",
      plugins: [
        "AMap.PlaceSearch",
        "AMap.Geocoder",
        "AMap.AutoComplete",
        "AMap.ToolBar",
        "AMap.Scale",
        "AMap.Marker",
        "AMap.Geolocation",
        "AMap.Polyline",
        "AMap.BasicControl",
        "AMap.GetRotation",
        "AMap.ControlBar",
        "AMap.SetPitch",
        "AMap.Circle",
      ],
      features: ["bg", "building", "road"],
    });

    map.value = new AMap.Map("custom-amap", {
      viewMode: "2D",
      zoom: 18,
      pitch: 50,
      center: defaultCenter, //默认中心点
      showIndoorMap: false,
      resizeEnable: true,
    });

    satelliteLayer.value = new AMap.TileLayer.Satellite();
    roadNetLayer.value = new AMap.TileLayer.RoadNet();
    //批量添加图层
    map.value.add([satelliteLayer.value, roadNetLayer.value]);

    if (!window.Loca) {
      await new Promise((resolve, reject) => {
        const script = document.createElement("script");
        script.src =
          "https://webapi.amap.com/loca?v=2.0&key=4382d57ce20d54c12e3c78ae23f76876";
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
      });
    }

    // 2. 用 window.Loca 创建实例
    loca.value = new window.Loca.Container({ map: map.value });
    flayLine(loca.value);

    // 绘制飞行轨迹
    drawFlightPath(AMap);
  } catch (err) {
    console.error("地图初始化失败:", err);
    error.value = "地图加载失败：" + (err.message || "未知错误");
  } finally {
    loading.value = false;
  }
};

const RenderinglineLayer = () => {
  // 更新渲染线段
  let arr = [];
  // 2D模式：使用地上坐标的连接线
  if (allData.value.length > 0) {
    // 创建地上坐标的线段数据
    const groundLineData = [];

    // 处理航点之间的连接线
    if (allData.value[0].points && allData.value[0].points.length > 1) {
      for (let i = 0; i < allData.value[0].points.length - 1; i++) {
        const startPoint = allData.value[0].points[i];
        const endPoint = allData.value[0].points[i + 1];

        groundLineData.push({
          type: "Feature",
          geometry: {
            type: "LineString",
            coordinates: [
              [startPoint[0], startPoint[1], 0], // 地上坐标
              [endPoint[0], endPoint[1], 0], // 地上坐标
            ],
          },
          properties: {
            color: "#ff0000",
            weight: 3,
          },
        });
      }
    }

    // 处理起飞点到第一个航点的连接线
    // if (
    //   allData.value[0].startdata &&
    //   allData.value[0].startdata.point &&
    //   allData.value[0].points.length > 0
    // ) {
    //   const startPoint = allData.value[0].startdata.point;
    //   const firstWaypoint = allData.value[0].points[0];

    //   groundLineData.push({
    //     type: "Feature",
    //     geometry: {
    //       type: "LineString",
    //       coordinates: [
    //         [startPoint[0], startPoint[1], 0], // 地上坐标
    //         [firstWaypoint[0], firstWaypoint[1], 0], // 地上坐标
    //       ],
    //     },
    //     properties: {
    //       color: "#00ff00",
    //       weight: 3,
    //     },
    //   });
    // }

    arr = groundLineData;
  }

  // 检查 lineLayer 是否存在
  if (window.lineLayer) {
    window.lineLayer.setSource(
      new window.Loca.GeoJSONSource({
        data: {
          type: "FeatureCollection",
          features: arr,
        },
      })
    );
    window.lineLayer.render();
  } else {
    console.error("window.lineLayer 不存在");
  }
};

// 绘制飞行轨迹
const drawFlightPath = (AMap) => {
  if (!map.value) return;
  // 初始化航线数据结构
  allData.value = [
    {
      name: "默认航线",
      // startdata: {
      //   lineData: null,
      //   guideLineData: null,
      //   point: [],
      //   marker: null,
      // },
      lineData: [],
      guideLineData: [],
      points: [],
      markers: [],
    },
  ];
  // const takeoffPoint = props.drawDefaultRoute[0].startdata.point;
  // allData.value[0].startdata.point = takeoffPoint;
  // // 创建起飞点标记
  // const takeoffMarker = new AMap.Marker({
  //   position: [takeoffPoint[0], takeoffPoint[1]],
  //   content: `<div style="display:flex;align-items:center;justify-content:center;width:30px;height:30px;font-weight:bold;color:white;background:#fff;border-radius:50%;"><img src="/static/flay.png" width="24" height="24" /></div>`,
  //   offset: new AMap.Pixel(-13, -20),
  //   extData: {
  //     altitude: 0, // 起飞点标记保持在地面
  //     index: -1,
  //     originalPosition: [takeoffPoint[0], takeoffPoint[1]],
  //   },
  //   draggable: true, // 允许起飞点拖动
  // });
  // map.value.add(takeoffMarker);
  // allData.value[0].startdata.marker = takeoffMarker;

  // 保存起飞点的原始位置，用于后续保护
  // const originalTakeoffPosition = [takeoffPoint[0], takeoffPoint[1]];
  // window.originalTakeoffPosition = originalTakeoffPosition;
  console.log(props.drawDefaultRoute[0].points, "默认数据");
  let waypoints = props.drawDefaultRoute[0].points;
  if (waypoints.length > 0) {
    waypoints.forEach((point, index) => {
      // 确保点数据格式正确 [lng, lat, height]
      const waypoint = Array.isArray(point)
        ? point
        : [
            point.lng || point[0],
            point.lat || point[1],
            point.height || point[2] || defaultHeight,
          ];
      // 创建带序号的航点标记
      // const waypointMarker = new AMap.Marker({
      //   position: [waypoint[0], waypoint[1]],
      //   content: `
      //     <div style="position: relative; width: 30px; height: 30px;">            
      //       <!-- 航点图标 -->
      //       <div style="
      //         position: absolute;
      //         top: 0px;
      //         left: 50%;
      //         transform: translateX(-50%);
      //         width: 30px;
      //         height: 30px;
      //         line-height: 30px;
      //         text-align: center;
      //         background: #fff;
      //         border: 2px solid white;
      //         border-radius: 50%;
      //         font-weight:700;
      //         box-shadow: 0 2px 4px rgba(0,0,0,0.2);
      //         color:#000;
      //       ">${index + 1}</div>
      //     </div>
      //   `,
      //   offset: new AMap.Pixel(-15, -15),
      //   extData: {
      //     altitude: waypoint[2],
      //     index: index,
      //     originalPosition: [waypoint[0], waypoint[1]],
      //   },
      //   draggable: true,
      // });
      // map.value.add(waypointMarker);
      // allData.value[0].markers.push(waypointMarker);
      allData.value[0].points.push(waypoint);

      // 创建航点辅助线 - 改为Point类型
      if (waypoint && waypoint.length >= 3) {
        allData.value[0].guideLineData.push({
          type: "Feature",
          geometry: {
            type: "Point",
            coordinates: [
              arithmetic.subtract(waypoint[0], offset),
              waypoint[1],
            ], // 地面点坐标
          },
          properties: {
            color: "#f4ed7c",
            h: waypoint[2], // 使用h属性，与mapvvvv.html保持一致
          },
        });
      }
    });

    for (let i = 0; i < allData.value[0].points.length - 1; i++) {
      const start = allData.value[0].points[i];
      const end = allData.value[0].points[i + 1];

      allData.value[0].lineData.push({
        type: "Feature",
        geometry: {
          type: "LineString",
          coordinates: [
            [start[0], start[1], start[2]],
            [end[0], end[1], end[2]],
          ],
        },
        properties: {
          color: "#3366ff",
          //   distance: segmentDistance,
        },
      });
    }
  }
  // 重新渲染图层
  RenderinglineLayer();
  // 将地图中心点设置为起飞点位置
  if (waypoints.length > 0) {
    map.value.setCenter([waypoints[0][0], waypoints[0][1]]);
    map.value.setZoom(18);
  }
  // if (
  //   allData.value[0].startdata.point &&
  //   allData.value[0].startdata.point.length > 0
  // ) {
  //   const takeoffPoint = allData.value[0].startdata.point;

  //   map.value.setCenter([takeoffPoint[0], takeoffPoint[1]]);
  //   map.value.setZoom(16); // 设置合适的缩放级别
  // }
};

// 组件卸载时清理
onUnmounted(cleanupMap);

// 暴露给父组件的方法
defineExpose({
  openMap: (data) => {
    console.log("打开地图并显示轨迹", data);
    // 这里可以根据传入的数据来显示特定的飞行轨迹
  },
  closeMap: handleClose,
});
</script>

<style lang="scss" scoped>
.amap-box {
  padding: 5px 0 0;

  #custom-amap {
    width: 700px;
    height: 400px;
    margin-top: 10px;
    border: 1px solid #ccc;
  }
}
</style>